/*工具栏
 * @Author: kevin.huang 
 * @Date: 2018-07-21 12:03:32 
 * @Last Modified by: kevin.huang
 * @Last Modified time: 2019-03-15 14:07:49
 * Copyright (c): kevin.huang Released under MIT License
 */
(function (global, factory) {
    if (typeof define === 'function' && define.amd  && !window["_all_in_"]) {
        define(['$B'], function (_$B) {
            return factory(global, _$B);
        });
    } else {
        if(!global["$B"]){
            global["$B"] = {};
        }
        factory(global, global["$B"]);
    }
}(typeof window !== "undefined" ? window : this, function (window, $B) {    
    var $body;
    function _getBody(){
        if(!$body){
            $body = $(window.document.body).css("position", "relative");
            if(!$body.attr("_k_d_w_c")){
                $body.click(function () {
                    $body.children("#k_toolbar_drop_wrap").hide();
                });
                if(window.top !== window){
                    try{
                        $(window.top.document.body).click(function(){
                            $body.children("#k_toolbar_drop_wrap").hide();
                        });
                    }catch(ex){
                    }
                }
                $body.attr("_k_d_w_c",1);
            }
        }
        return $body;        
    }    
    var btnHtml = "<button  style='{bg}' cmd='{cmd}' id='{id}' class='k_toolbar_button k_box_size btn k_toolbar_button_{cls}'>{text}</button>";
    var disabledCls = "k_toolbar_button_disabled";
    function _btnClickHandler(e) {       
        var $t = $(this);
        if ($t.hasClass(disabledCls)) {
            return false;
        }
        if (!e.data["priv"]) {
            $B.alert({
                message: $B.permission
            });
            return false;
        }
        var ctx = $t;
        var _this = e.data._t;
        if (_this.opts.context) {
            ctx = _this.opts.context;
        }
        var clickEvent = $t.data("click");
        var methodsName = $t.data("methodsObject");
        if(!methodsName){
            methodsName = _this.opts.methodsObject;
        }
        if (typeof  clickEvent === 'function') {
            setTimeout(function() {
                clickEvent.call(ctx, $t.data("params"));
            }, 1);            
        } else {
            var mObj = window[methodsName];
            if (mObj && typeof mObj[clickEvent] === 'function') {               
                setTimeout(function() {
                    mObj[clickEvent].call(ctx, $t.data("params"));
                }, 1);
            }
        }
        if (e.data.wrap) {
            e.data.wrap.hide();
        }
        if (_this.opts.onOperated) {            
            setTimeout(function() {
                _this.opts.onOperated.call(ctx, $t.data("params"));
            }, 1);
        }     
        return false;
    }
    function createButton(opt,btnTxt,isGroup) {
        var _tool_timerOuter = null;
        var txt = this.opts.showText ? btnTxt : '';
        var _this = this ,bg,fontColor;
        bg = opt.color ? ("background-color:" + opt.color + ";") : '';
        if(bg === "" && this.opts.color && this.opts.color !== ""){
            bg = "background-color:" + this.opts.color + ";";
        }
        fontColor = opt.fontColor ? ("color:" + opt.fontColor) : '';
        if(fontColor === "" && this.opts.fontColor && this.opts.fontColor !== ""){
            fontColor = "color:" + this.opts.fontColor + ";";
        }
        if (fontColor !== "") {
            bg = bg + fontColor;
        }
        var html = btnHtml.replace("{cmd}", opt.cmd).replace("{id}", opt.id).replace("{cls}", this.opts.style).replace("{text}", txt).replace("{bg}", bg);
        if (this.opts.params) {
            delete this.opts.params.Toolbar;
        }
        var $btn = $(html).appendTo(this.buttonWrap).data("params", $.extend({
            cmd: opt.cmd
        }, this.opts.params, opt.params));
        var returnBtn = $btn;
        if(isGroup){
            $btn.css({"margin-right":0,"border-radius":0,"-moz-border-radius":0,"-webkit-border-radius":0});
        }
        if (opt.disabled) {
            $btn.addClass(disabledCls);
        }
        if(txt === ""){
            $btn.attr("title", opt.text);
        }
        $btn.data("click", opt.click);
        if (opt.iconCls && opt.iconCls !== '') {
            var isPlain = _this.opts.style === 'plain';
            if (isPlain) {
                $btn.attr("title", btnTxt).css("background", "none");                
            }
            var fs = "";
            if (_this.opts.fontSize) {
                fs = "style='font-size:" + _this.opts.fontSize + "px'";
            }
            if (opt.childrens && opt.childrens.length > 0) {
                $btn.append('<i style="padding-left:4px" ' + fs + ' class="fa ' + opt.iconCls + '"></i>&nbsp');
            } else {
                $btn.prepend('<i ' + fs + ' class="fa ' + opt.iconCls + '"></i>&nbsp');
            }
            var iconColor = "#ffffff";
            if (opt.iconColor) {
                iconColor = opt.iconColor;                
            }else if(isPlain && opt.color){
                iconColor = opt.color;
            }else if(this.opts.iconColor){
                iconColor = this.opts.iconColor;
            }
            $btn.children("i").css("color", iconColor);
            if(isPlain){
                $btn.css("color",iconColor);
            }
        }
        //权限判断
        var params = $btn.data("params");
        if (params) {
            var privilage = params["privilage"];
            var priv = true;
            if (typeof privilage !== 'undefined' && privilage === "0") {
                priv = false;
                delete $btn.data("params")["privilage"];
                $btn.addClass("k_no_privilage_cls").css("color", "#D1D1D1");
            }
        }
        $btn.on("click", {
            _t: _this,
            priv: priv
        }, _btnClickHandler).data("methodsObject", opt.methodsObject);

        if (opt.childrens && opt.childrens.length > 0) {
            var wrap;
            $btn.mouseenter(function (e) {
                var $t = $(this),
                    _this = $t.data("ins"),
                    ofs = $t.offset(),
                    childrens = $t.data("childrens"),
                    minWidth = $t.outerWidth();
                wrap = _getBody().children("#k_toolbar_drop_wrap");
                if (wrap.length === 0) {
                    wrap = $("<div id='k_toolbar_drop_wrap' style='width:auto;position:absolute;display:none;top:-1000px;' class='k_box_size k_box_shadow'></div>").appendTo(_getBody());
                    wrap.mouseenter(function () {
                        clearTimeout(_tool_timerOuter);
                    }).mouseout(function (e) {
                        var $t = $(this);
                        var mleft = e.pageX,
                            mtop = e.pageY,
                            w = $t.outerWidth(),
                            h = $t.outerHeight(),
                            ofs = $t.offset();
                        var isInner = mleft >= ofs.left && mleft <= (ofs.left + w) && mtop > ofs.top && mtop <= (ofs.top + h);
                        if (!isInner) {
                            _tool_timerOuter = setTimeout(function () {
                                if (wrap) {
                                    wrap.hide();
                                }
                            }, 1500);
                        }
                    });
                } else {
                    wrap.children().remove();
                }
                var _top = ofs.top + $t.outerHeight() - 1;
                var _cs = {
                    top: "-1000px",
                    left: ofs.left,
                    "min-width": minWidth
                };
                wrap.css(_cs).show();
                for (var i = 0, len = childrens.length; i < len; ++i) {
                    var opt = childrens[i],
                        txt = _this.opts.showText ? opt.text : '',
                        methodsObject = opt["toolMethods"],
                        bg = opt.color ? ("background-color:" + opt.color) :  _this.opts.color;
                    var html = btnHtml.replace("{cmd}", opt.cmd).replace("{id}", opt.id).replace("{cls}", _this.opts.style).replace("{text}", txt).replace("{bg}", bg);
                    var $btn = $(html).appendTo(wrap).data("params", $.extend({
                        cmd: opt.cmd
                    }, _this.opts.params, opt.params));
                    if (opt.disabled) {
                        $btn.addClass(disabledCls);
                    }
                    if(txt === ""){
                        $btn.attr("title", opt.text);
                    }
                    $btn.data("click", opt.click);
                    //权限判断
                    var privilage = $btn.data("params")["privilage"];
                    var priv = true;
                    if (typeof privilage !== 'undefined' && privilage === "0") {
                        priv = false;
                        delete $btn.data("params")["privilage"];
                        $btn.addClass("k_no_privilage_cls").css("color", "#D1D1D1");
                    }
                    $btn.on("click", {
                        _t: _this,
                        wrap: wrap,
                        priv: priv
                    }, _btnClickHandler).data("methodsObject", opt.methodsObject);

                    if (opt.iconCls && opt.iconCls !== '') {
                        if (_this.opts.style === 'plain') {
                            $btn.attr("title", opt.text);
                        }
                        var fs = "";
                        if (_this.opts.fontSize) {
                            fs = "style='font-size:" + _this.opts.fontSize + "px'";
                        }
                        var iconColor =  opt.color ? opt.color : "#666666";
                        $btn.prepend('<i style="color:'+iconColor+';" ' + fs + ' class="fa ' + opt.iconCls + '"></i>&nbsp');
                    }
                }
                var _wrapHeight = wrap.outerHeight(),
                    inf_height = _wrapHeight + _top;
                var docWidth = _getBody().width();
                var wrapWidth = wrap.outerWidth() + 10;
                var avilableWidth = docWidth - ofs.left;
                var diffLeft = wrapWidth - avilableWidth;
                if (diffLeft > 0) {
                    wrap.css("left", ofs.left - diffLeft);
                }
                if (inf_height > _getBody().height()) {
                    _top = ofs.top - _wrapHeight;
                }                
                wrap.css("top",_top);                
                wrap.children().mouseover(function () {
                    clearTimeout(_tool_timerOuter);
                });
                return false;
            }).data("childrens", opt.childrens)
                .data("ins", _this).parent().mouseenter(function () {
                    if (wrap) {
                        wrap.hide();
                    }
                });
        }
        return returnBtn;
    }
    var Toolbar = function (jqObj, opts) {
        var defaultOpts = {
            params: null, //用于集成到tree datagrid时 行按钮的数据参数
            methodsObject: 'methodsObject', //事件集合对象
            align: 'left', //对齐方式，默认是left 、center、right
            style: 'normal', // plain / min  / normal /  big
            showText: true, // min 类型可以设置是否显示文字
            onOperated: undefined,//点击任何按钮都触发的回调
            buttons: [] //请参考buttons
        };
        $B.extend(this, Toolbar); //继承父类
        this.jqObj = jqObj.addClass("k_toolbar_main");
        this.buttonWrap = $("<div></div>").appendTo(this.jqObj);
        this.opts = $.extend({}, defaultOpts, opts);
        if (this.opts.align === 'center') {
            this.jqObj.css("text-align", "center");
            this.buttonWrap.css("width", "100%");
        } else {
            this.buttonWrap.css("float", this.opts.align);
            this.jqObj.addClass("clearfix");
        }
        for (var i = 0, l = this.opts.buttons.length; i < l; ++i) {
            var opt = this.opts.buttons[i];
            if($.isArray(opt)){
                var lastBtn;
                for(var j = 0 ,jlen = opt.length ; j < jlen; ++j){
                    lastBtn = this._createButtonByopt(opt[j],true);
                }
                if(i !== l -1){
                    lastBtn.css("border-right","1px solid #C1C1C1");
                }               
            }else{
                this._createButtonByopt(opt,false);
            }            
        }
    };
    Toolbar.prototype = {
        constructor: Toolbar,
        _createButtonByopt:function(opt,isGroup){
            var created = true;
            if (typeof opt.visualable !== 'undefined') {
                created = opt.visualable;
            }
            if (created) {
                return createButton.call(this, opt, opt.text,isGroup);
            }
        },
        /**
         *启用按钮（可以批量启用）
         *args  btnIds=[] //按钮的id数组
         ***/
        enableButtons: function (args) {           
            for (var i = 0, l = args.length; i < l; ++i) {
                var id = args[i];
                this.buttonWrap.children("#" + id).removeClass("k_toolbar_button_disabled");
            }
        },
        /**
         *禁用按钮（可以批量禁用）
         *args  btnIds=[] //按钮的id数组
         ***/
        disableButtons: function (args) {
            for (var i = 0, l = args.length; i < l; ++i) {
                var id = args[i];
                this.buttonWrap.children("#" + id).addClass("k_toolbar_button_disabled");
            }
        },
        /***
         *删除按钮（可以批量删除）
         *args btnIds=[] //按钮的id数组
         ***/
        delButtons: function (args) {
            for (var i = 0, l = args.length; i < l; ++i) {
                var id = args[i];
                this.buttonWrap.children("#" + id).remove();
            }
        },
        /**
         *添加按钮（可以批量添加）
         *args buttons=[]//按钮的json配置
         ***/
        addButtons: function (args) {
            for (var i = 0, l = args.length; i < l; ++i) {
                var opt = args[i];
                var txt = this.opts.showText ? opt.text : '';
                createButton.call(this, opt, txt);
            }
        },
        /***
         * 更新参数
         * ***/
        updateParams: function (args) {
            $.extend(this.opts.params, args);
        }
    };
    if($B){
        $B["Toolbar"] = Toolbar;
    }else{
        console.log("exception >>>");
    }   
    return Toolbar;
}));